# src/models/portfolio.py
from pydantic import BaseModel, Field
from typing import Dict, List, Optional, Any
from datetime import datetime
from enum import Enum

class OptimizationAlgorithm(str, Enum):
    NSGA2 = "nsga2"
    MOEAD = "moead"
    SAC = "sac"
    MOPSO = "mopso"
    SIMULATED_ANNEALING = "sa"

class Asset(BaseModel):
    symbol: str
    name: str
    sector: str
    esg_score: Optional[float] = None
    current_price: float

class Objective(BaseModel):
    return_weight: float = Field(ge=0, le=1)
    risk_weight: float = Field(ge=0, le=1)
    esg_weight: float = Field(ge=0, le=1)
    cost_weight: float = Field(ge=0, le=1)

class Constraint(BaseModel):
    max_single_weight: float = Field(ge=0, le=1, default=0.2)
    min_cash_ratio: float = Field(ge=0, le=1, default=0.1)
    max_sector_weight: float = Field(ge=0, le=1, default=0.3)
    max_turnover: float = Field(ge=0, default=0.5)

class Solution(BaseModel):
    weights: Dict[str, float]
    metrics: Dict[str, float]
    timestamp: datetime
    
class ParetoSet(BaseModel):
    solutions: List[Solution]
    generation: int
    algorithm: OptimizationAlgorithm

class MarketChangeDetection(BaseModel):
    is_change: bool
    p_value: float
    trigger_at: datetime
    detection_method: str
